﻿using System;
using System.Collections.Generic;
using InterfaceLiftLib.Attributes;
using InterfaceLiftLib.Converters.Enums;
using InterfaceLiftLib.Models;
using InterfaceLiftLib.Models.Enums;

namespace InterfaceLiftLib.Service
{
    /// <summary>
    /// Represents a collection of methods exposed by the Interfacelift web service.
    /// For a more detailed documentation see https://www.mashape.com/interfacelift/wallpapers#!documentation
    /// </summary>
    public interface IInterfaceLiftService
    {
        /// <summary>
        /// Interchangeable-lens camera body.
        /// </summary>
        /// <param name="id">Unique identifier for the camera body.</param>
        [WebServiceMethodName("camera")]
        void GetCameraBody(int id, Action<CameraBody, Exception> callback = null);

        /// <summary>
        /// Lens for an interchangeable-lens camera.
        /// </summary>
        /// <param name="id">Unique identifier for a camera lens.</param>
        [WebServiceMethodName("lens")]
        void GetCameraLens(int id, Action<CameraLens, Exception> callback = null);

        /// <summary>
        /// User-submitted comment about a Wallpaper featured on InterfaceLIFT.
        /// </summary>
        /// <param name="id">Unique identifier for the comment.</param>
        [WebServiceMethodName("comment")]
        void GetComment(int id, Action<Comment, Exception> callback = null);

        /// <summary>
        /// A time-ordered array of comments about a specific 'Wallpaper' and/or posted by a specific 'User'.
        /// </summary>
        /// <param name="wallpaperId">Unique identifier of a Wallpaper object.</param>
        /// <param name="userId">Unique identifier of a User object.</param>
        /// <param name="sortOrder">Sort the comment array in ascending or descending time order.</param>
        /// <param name="start">The number of objects to skip over in the result set. Pair this parameter with 'limit' in order to implement paging of results.</param>
        /// <param name="limit">Maximum number of comments to return.</param>
        [WebServiceMethodName("comments")]
        void GetComments([QueryStringParameter] int wallpaperId = 0,
                         [QueryStringParameter] int userId = 0,
                         [QueryStringParameter] [EnumConverter(typeof (SortOrderConverter))] SortOrder sortOrder = SortOrder.Ascending,
                         [QueryStringParameter] int start = 0,
                         [QueryStringParameter] int limit = 0,
                         Action<IEnumerable<Comment>, Exception> callback = null);

        /// <summary>
        /// User favorites wallpapers.
        /// </summary>
        /// <param name="userId">Unique ID of a User.</param>
        /// <param name="limit">Maximum number of objects to return. Default is 10 objects if not explicitly specified.</param>
        /// <param name="resolution">If a screen resolution is provided, the resulting list will only contain 'Wallpaper' objects available in that resolution.</param>
        /// <param name="sortBy">The attribute by which to sort 'Wallpaper' objects returned by the request. Default is 'date' if not explicitly specified.</param>
        /// <param name="sortOrder">Order the 'Wallpaper' objects by the 'sort_by' attribute' in ascending or descending order. Default is 'desc' if not explicitly specified.</param>
        /// <param name="start">The number of objects to skip over in the result set. Pair this parameter with 'limit' in order to implement paging of results.</param>
        [WebServiceMethodName("favorites")]
        void GetFavoritesWallpapers(int userId,
                                    [QueryStringParameter] int limit = 0,
                                    [QueryStringParameter] Resolution resolution = null,
                                    [QueryStringParameter] [EnumConverter(typeof(SortByConverter))] SortBy sortBy = SortBy.Nothing,
                                    [QueryStringParameter] [EnumConverter(typeof(SortOrderConverter))] SortOrder sortOrder = SortOrder.Descending,
                                    [QueryStringParameter] int start = 0,
                                    Action<IEnumerable<Wallpaper>, Exception> callback = null);

        /// <summary>
        /// Tag, category, or keyword.
        /// </summary>
        /// <param name="id">Unique identifier.</param>
        [WebServiceMethodName("tag")]
        void GetTag(int id, Action<Tag, Exception> callback = null);

        /// <summary>
        /// Array of tags/categories/keywords matching the search criteria.
        /// </summary>
        /// <param name="search">Search keyword text.</param>
        /// <param name="type">Type of tag.</param>
        [WebServiceMethodName("tags")]
        void GetTags([QueryStringParameter] string search,
                     [QueryStringParameter] [EnumConverter(typeof(TagTypeConverter))] TagType type,
                     Action<IEnumerable<Tag>, Exception> callback = null);

        /// <summary>
        /// Infos about a specific User.
        /// </summary>
        /// <param name="id">Unique ID of User.</param>
        [WebServiceMethodName("user")]
        void GetUserInfos(int id, Action<User, Exception> callback = null);

        /// <summary>
        /// Returns a 'Wallpaper' object.
        /// </summary>
        /// <param name="id">Unique ID of the desired 'Wallpaper' object.</param>
        [WebServiceMethodName("wallpaper")]
        void GetWallpaper(int id, Action<Wallpaper, Exception> callback = null);

        /// <summary>
        /// Array of 'Wallpaper' objects. All parameters are optional. The ten most-recent 'Wallpaper' objects are returned by default.
        /// </summary>
        /// <param name="limit">Maximum number of objects to return. Default is 10 objects if not explicitly specified.</param>
        /// <param name="resolution">If a screen resolution is provided, the resulting list will only contain 'Wallpaper' objects available in that resolution.</param>
        /// <param name="sortBy">The attribute by which to sort 'Wallpaper' objects returned by the request. Default is 'date' if not explicitly specified.</param>
        /// <param name="ascending">Order the 'Wallpaper' objects by the 'sort_by' attribute' in ascending or descending order. Default is 'desc' if not explicitly specified.</param>
        /// <param name="startFrom">The number of objects to skip over in the result set. Pair this parameter with 'limit' in order to implement paging of results.</param>
        [WebServiceMethodName("wallpapers")]
        void GetWallpapers([QueryStringParameter] uint limit = 0,
                           [QueryStringParameter] Resolution resolution = null,
                           [QueryStringParameter] [EnumConverter(typeof(SortByConverter))] SortBy sortBy = SortBy.Nothing,
                           [QueryStringParameter] bool ascending = true,
                           [QueryStringParameter] int startFrom = 0,
                           Action<IEnumerable<Wallpaper>, Exception> callback = null);

        /// <summary>
        /// An object containing the download URL for the specified 'wallpaper_id' and image 'resolution'.
        /// Please note that each 'Wallpaper Download' object retrieved counts against your 'Downloads' limit regardless of whether or not the 'download_url' is accessed. 
        /// For that reason, you should only request this object when the end user actually attempts a download.
        /// </summary>
        /// <param name="wallpaperId">Unique identifier for the 'Wallpaper'.</param>
        /// <param name="resolution">Image resolution to download.</param>
        /// <param name="callback"></param>
        [WebServiceMethodName("wallpaper_download")]
        void GetWallpaperDownloadInfos(int wallpaperId, Resolution resolution, Action<WallpaperDownloadInfos, Exception> callback = null);
    }
}
